package cqrtplm.service.impl;


import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.text.CharSequenceUtil;
import com.alibaba.fastjson.JSON;
import com.hustcad.plm.basic.util.TyCommonExtUtil;
import com.hustcad.plm.basic.util.TyplmEntityBaseUtil;
import com.hustcad.plm.basic.util.TyplmLoggerUtil;
import com.hustcad.plm.caddocapi.service.TyplmCADDescLinkService;
import com.hustcad.plm.caddocapi.service.TyplmCADRelObjectService;
import com.hustcad.plm.pdm.basedrule.dto.TyplmBaseRuleBoundedObjDTO;
import com.hustcad.plm.pdm.caddoc.model.vo.CadLinkPartBasicInfoVO;
import com.hustcad.plm.pdm.caddoc.model.vo.CadLinkPartVO;
import com.hustcad.plm.pdm.common.util.CommonUtil;
import com.hustcad.plm.pdm.common.util.TyplmPermissionsUtil;
import com.hustcad.plm.pdm.ec.mapper.TyplmChgNoticeActivityLinkMapper;
import com.hustcad.plm.pdm.ec.module.EngineeringChangeErrorCodeEnum;
import com.hustcad.plm.pdm.ec.module.dto.*;
import com.hustcad.plm.pdm.ec.module.vo.ChgFormVO;
import com.hustcad.plm.pdm.ec.module.vo.ECObjDataVO;
import com.hustcad.plm.pdm.ec.service.*;
import com.hustcad.plm.pdm.ec.util.TyCommonSearchUtil;
import com.hustcad.plm.pdm.ec.util.TyHandleEcCommonUtil;
import com.hustcad.plm.pdm.enumeration.service.TyplmLocalePropertyValueService;
import com.hustcad.plm.pdm.file.service.TyFileHandleService;
import com.hustcad.plm.pdm.partbom.service.TyplmPartRelObjectService;
import com.hustcad.plm.pdm.type.service.TyplmTypeService;
import com.hustcad.plm.pdm.user.service.TyplmUserService;
import com.hustcad.plm.pdm.workflow.model.entity.WorkFlowContainer;
import com.hustcad.plm.pdm.workflow.service.TyplmFlowContainerObjectService;
import com.hustcad.plm.pdm.workflow.service.TyplmWorkFlowContainerService;
import com.ty.basic.common.ITyCompanyVersioned;
import com.ty.basic.common.ITyCreator;
import com.ty.basic.common.ITyIterated;
import com.ty.basic.entity.CTyEntityBaseDO;
import com.ty.basic.entity.CTyIterateBaseDO;
import com.ty.basic.entity.IdentifierEntity;
import com.ty.basic.entity.cad.CADDocDO;
import com.ty.basic.entity.change.ChgActivityDO;
import com.ty.basic.entity.change.ChgNoticeDO;
import com.ty.basic.entity.org.UserDO;
import com.ty.basic.entity.part.PartDO;
import com.ty.basic.entity.type.TypeDO;
import com.ty.basic.handler.exceptionhandler.exception.ResponseCodeEnum;
import com.ty.basic.handler.exceptionhandler.exception.TyException;
import com.ty.basic.session.TyAccountContext;
import com.ty.basic.util.TyEntityMapperUtil;
import cqrtplm.service.OperateChangeObjectService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigInteger;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @Author：hxm
 * @DATE: 2025/7/7 14:59
 */

@Slf4j
@Service
@Transactional
public class OperateChangeObjectServiceImpl implements OperateChangeObjectService {
    @Resource
    private TyplmChgActivityService typlmChgActivityService;
    @Resource
    private TyChangeObjectLinkExtService changeObjectLinkExtService;
    @Resource
    private TyplmTypeService typlmTypeService;
    @Resource
    private TyChangeCheckService tyChangeCheckService;
    @Resource
    private TyplmLocalePropertyValueService typlmLocalePropertyValueService;
    @Resource
    private TyplmChangeObjectLinkService typlmChangeObjectLinkService;
    @Resource
    private TyplmPermissionsUtil typlmPermissionsUtil;
    @Resource
    private TyplmChgNoticeQueryService typlmChgNoticeQueryService;
    @Resource
    private TyplmFlowContainerObjectService typlmFlowContainerObjectService;
    @Resource
    private TyChangeExtService tyChangeExtService;
    @Resource
    private TyplmChgNoticeActivityLinkMapper typlmChgNoticeActivityLinkMapper;
    @Resource
    private TyplmCADRelObjectService typlmCADRelObjectService;
    @Resource
    private TyplmPartRelObjectService typlmPartRelObjectService;
    @Resource
    private TyFileHandleService tyFileHandleService;
    @Resource
    private TyplmWorkFlowContainerService typlmWorkFlowContainerService;
    @Resource
    private TyplmCADDescLinkService typlmCADDescLinkService;
    @Resource
    private TyplmUserService typlmUserService;

    private CreateECADTO createEca(ChgFormVO formVO, CreateECODTO ecn, TyplmBaseRuleBoundedObjDTO ecnRuleInfo) {
        TypeDO typeDO = this.typlmTypeService.getLastTypeByLogicalidentifier("ty.inteplm.change.CTyChangeActivity");
        UserDO user = CommonUtil.getUser();
        CreateECADTO eca = new CreateECADTO();
        eca.setUserDO(user);
        eca.setCreator(user.getName());
        eca.setOwner(user.getName());
        eca.setActivitynumber("eca" + System.currentTimeMillis());
        eca.setContaineroid(formVO.getContainerOid());
        eca.setContainerotype(formVO.getContainerOtype());
        eca.setEcoId(ecn.getOid());
        eca.setLifecycletemplateoid(ecnRuleInfo.getLifeCycleTemplateOid());
        eca.setOtype("ty.inteplm.change.CTyChangeActivity");
        eca.setTypeDefName(typeDO.getName());
        eca.setSecuritylabels(formVO.getSecuritylabels());
        TyplmLoggerUtil.debug(log, () -> "构建的待添加的eca信息为==>【{}】", () -> new Object[]{JSON.toJSONString(eca)});
        this.typlmChgActivityService.batchCreateECA(Collections.singletonList(eca));
        return eca;
    }

    private List<ChgActivityDO> setEcaListWhenIsNull(List<ChgActivityDO> ecaList, IdentifierEntity entity) {
        if (CollectionUtils.isEmpty(ecaList)) {
            ChgNoticeDO chgNoticeDO = this.typlmChgNoticeQueryService.selectByPrimaryKey(entity.getOid());
            ChgFormVO chgFormVO = new ChgFormVO();
            chgFormVO.setContainerOid(chgNoticeDO.getContaineroid());
            chgFormVO.setContainerOtype(chgNoticeDO.getContainerotype());
            CreateECODTO createECODTO = new CreateECODTO();
            createECODTO.setOid(entity.getOid());
            TyplmBaseRuleBoundedObjDTO typlmBaseRuleBoundedObjDTO = new TyplmBaseRuleBoundedObjDTO();
            typlmBaseRuleBoundedObjDTO.setLifeCycleTemplateOid(chgNoticeDO.getLifecycletemplateoid());
            CreateECADTO eca = this.createEca(chgFormVO, createECODTO, typlmBaseRuleBoundedObjDTO);
            ChgActivityDO chgActivityDO = new ChgActivityDO();
            BeanUtils.copyProperties(eca, chgActivityDO);
            return Collections.singletonList(chgActivityDO);
        } else {
            return ecaList;
        }
    }

    private void createEcObjAndEcaLink(List<ChgActivityDO> ecaList, List<ECObjDTO> ecObjDTOS, Boolean before) {
        if (CollectionUtils.isNotEmpty(ecaList)) {
            ChgActivityDO eca = (ChgActivityDO) ecaList.get(0);
            IdentifierEntity identifierEntity = new IdentifierEntity(eca.getOid(), eca.getOtype());
            this.changeObjectLinkExtService.createECObjDataLinkList(identifierEntity, ecObjDTOS, before);
        }

    }


    @Transactional(
            rollbackFor = {Exception.class}
    )
    public List<ECObjDataVO> addBeforeChangeObjectWithStrategy(ECAddChangeObjectDTO addChangeObjectDTO) {
        IdentifierEntity entity = addChangeObjectDTO.getEntity();
        TyplmLoggerUtil.debug(log, () -> "变更单添加变更对象的主对象为==>【{}】",
                              () -> new Object[]{JSON.toJSONString(entity)});
        Boolean before = Boolean.TRUE;
        List<ECObjData> allObjDTOList = addChangeObjectDTO.getAllObjDTOList();
        TyplmLoggerUtil.debug(log, () -> "变更对象全量列表为==>【{}】",
                              () -> new Object[]{JSON.toJSONString(allObjDTOList)});
        List<ECObjDTO> entityList = addChangeObjectDTO.getEntityList();
        if (TyAccountContext.isDebug()) {
            log.info("需要添加的变更对象列表为==>【{}】", JSON.toJSONString(entityList));
        }

        if (CollUtil.isEmpty(entityList)) {
            return CollUtil.isNotEmpty(allObjDTOList) ? new ArrayList(allObjDTOList) : new ArrayList();
        } else {
            if (entity != null && !TyplmEntityBaseUtil.isEmptyOid(entity.getOid())) {
                CTyEntityBaseDO ecIdentity = CommonUtil.getEntity(entity);
                TyplmLoggerUtil.debug(log, () -> "校验当前用户【{}】是否具有变更对象【{}】的修改权限",
                                      () -> new Object[]{JSON.toJSONString(CommonUtil.getUser()), JSON.toJSONString(
                                              ecIdentity)});
                this.typlmPermissionsUtil.checkObjectPermissionList(CommonUtil.getUser(),
                                                                    Collections.singletonList(ecIdentity), "修改");
            }

            this.checkEcnAndAllLinkObject(entity, allObjDTOList, before);
            entityList = this.filterDuplicateChangeObject(allObjDTOList, entityList);
            this.tyChangeExtService.checkChangeAddObject(entityList, before);
            if (Objects.nonNull(entity)) {
                return this.addObjectBeforeChangeWithStrategy(entity, entityList, Boolean.TRUE);
            } else {
                if (CollUtil.isNotEmpty(allObjDTOList)) {
                    List<IdentifierEntity> collect = (List) allObjDTOList.stream().map(
                            (itemx) -> new IdentifierEntity(itemx.getOid(), itemx.getOtype())).collect(
                            Collectors.toList());

                    for (ECObjData item : this.typlmChangeObjectLinkService.convertObjToEcDataInfo(collect)) {
                        ECObjDTO ecObjDTO = new ECObjDTO();
                        ecObjDTO.setOid(item.getOid());
                        ecObjDTO.setOtype(item.getOtype());
                        ecObjDTO.setIdentifierRef(new IdentifierEntity(item.getOid(), item.getOtype()));
                        entityList.add(ecObjDTO);
                    }
                }

                if (CollUtil.isEmpty(entityList)) {
                    return CollUtil.isNotEmpty(allObjDTOList) ? new ArrayList(allObjDTOList) : new ArrayList();
                } else {
                    List<ECObjDataVO> firstReturnResult = this.batchTransformEntityToECObject(entity,
                                                                                              entityList,
                                                                                              before);
                    if (CollUtil.isEmpty(allObjDTOList)) {
                        TyHandleEcCommonUtil.sortListByObjectName(firstReturnResult);
                        return firstReturnResult;
                    } else {
                        Map<BigInteger, List<CTyIterateBaseDO>> relationObjectMap = this.getECObjDataRelationObjectByList(
                                allObjDTOList);
                        this.resetAddObjectChangeStrategy(allObjDTOList, firstReturnResult, relationObjectMap);
                        this.compareChangeObject(allObjDTOList, firstReturnResult);
                        TyHandleEcCommonUtil.sortListByObjectName(firstReturnResult);
                        return firstReturnResult;
                    }
                }
            }
        }
    }


    private void compareChangeObject(List<ECObjData> allObjDTOList, List<ECObjDataVO> firstReturnResult) {
        if (!CollUtil.isEmpty(allObjDTOList) && !CollUtil.isEmpty(firstReturnResult)) {
            Map<BigInteger, ECObjData> allOidDataMap = (Map) allObjDTOList.stream().collect(
                    Collectors.toMap(ECObjDataVO::getOid, Function.identity(), (a, b) -> a));
            List<BigInteger> toHandleOidList = new ArrayList();
            List<ECObjData> toHandleOidDataList = new ArrayList();

            for (ECObjDataVO ecObjDataVO : firstReturnResult) {
                if (Objects.nonNull(allOidDataMap.get(ecObjDataVO.getOid()))) {
                    toHandleOidList.add(ecObjDataVO.getOid());
                    toHandleOidDataList.add(allOidDataMap.get(ecObjDataVO.getOid()));
                }
            }

            firstReturnResult.removeIf((item) -> toHandleOidList.contains(item.getOid()));
            firstReturnResult.addAll(new ArrayList(toHandleOidDataList));
        }
    }

    private void checkEcnAndAllLinkObject(IdentifierEntity entity, List<ECObjData> allObjDTOList, Boolean before) {
        if (TyAccountContext.isDebug()) {
            log.info(
                    "检查主对象和前端传的全量列表的入参为==>主对象entity = 【{}】,全量对象allObjDTOList = 【{}】,前后标记before = 【{}】",
                    new Object[]{JSON.toJSONString(entity), JSON.toJSONString(allObjDTOList), before});
        }

        if (!Objects.isNull(entity)) {
            if (!"ty.inteplm.change.CTyChangeNotice".equals(entity.getOtype())) {
                throw EngineeringChangeErrorCodeEnum.ONLY_ECN_PROCESS_CAN_ADD_OBJECT.getException(new Object[0]);
            } else if (!Objects.isNull(entity.getOid()) && !BigInteger.ZERO.equals(entity.getOid())) {
                List<ChgActivityDO> activityDOList = this.typlmChgNoticeActivityLinkMapper.queryECAByECNId(
                        entity.getOid());
                if (!CollUtil.isEmpty(activityDOList)) {
                    List<ECObjDataVO> allBeforeObjVoList = new ArrayList();

                    for (ChgActivityDO activityDO : activityDOList) {
                        allBeforeObjVoList.addAll(
                                this.typlmChangeObjectLinkService.queryECObjList(activityDO.getIdentifierRef(),
                                                                                 before));
                    }

                    if (CollUtil.isEmpty(allObjDTOList)) {
                        allObjDTOList = new ArrayList();
                    }

                    if (CollUtil.isNotEmpty(allBeforeObjVoList)) {
                        allObjDTOList.clear();
                        allObjDTOList.addAll(Convert.toList(ECObjData.class, allBeforeObjVoList));
                    }

                }
            }
        }
    }

    private List<ECObjDTO> filterDuplicateChangeObject(List<ECObjData> allObjDTOList, List<ECObjDTO> entityList) {
        if (CollUtil.isEmpty(entityList)) {
            return entityList;
        } else {
            List<ECObjData> var14 = (List) ObjectUtils.defaultIfNull(allObjDTOList, new ArrayList());
            List<ECObjDTO> result = new ArrayList();
            Map<BigInteger, ECObjDTO> collect = new HashMap();
            List<IdentifierEntity> queryList = new ArrayList();

            for (ECObjDTO ecObjDTO : entityList) {
                collect.put(ecObjDTO.getOid(), ecObjDTO);
                queryList.add(ecObjDTO.getIdentifierRef());
            }

            Map<IdentifierEntity, CTyEntityBaseDO> entityMap = CommonUtil.getEntityMap(queryList);
            if (CollUtil.isEmpty((Collection) var14)) {
                var14 = new ArrayList();
            }

            Map<BigInteger, ECObjData> allDataMap = (Map) ((List<ECObjData>) var14).stream().collect(
                    Collectors.toMap((item) -> Objects.isNull(item.getBranchid()) ? item.getOid() : item.getBranchid(),
                                     Function.identity(), (a, b) -> a));

            for (Map.Entry<IdentifierEntity, CTyEntityBaseDO> entry : entityMap.entrySet()) {
                IdentifierEntity key = (IdentifierEntity) entry.getKey();
                CTyEntityBaseDO value = (CTyEntityBaseDO) entry.getValue();
                BigInteger checkKey = key.getOid();
                if (value instanceof ITyIterated) {
                    checkKey = ((ITyIterated) value).getBranchid();
                }

                ECObjData ecObjData = (ECObjData) allDataMap.get(checkKey);
                if (Objects.nonNull(ecObjData)) {
                    collect.remove(key.getOid());
                }
            }

            if (CollUtil.isNotEmpty(collect)) {
                result.addAll(new ArrayList(collect.values()));
            }

            TyplmLoggerUtil.debug(log, () -> "过滤添加变更的重复数据后可添加数据为==>【{}】",
                                  () -> new Object[]{JSON.toJSONString(result)});
            return result;
        }
    }

    private void resetAddObjectChangeStrategy(List<ECObjData> allObjDTOList, List<ECObjDataVO> firstReturnResult,
                                              Map<BigInteger, List<CTyIterateBaseDO>> relationObjectMap) {
        if (!CollUtil.isEmpty(allObjDTOList) || !CollUtil.isEmpty(firstReturnResult) || !CollUtil.isEmpty(
                relationObjectMap)) {
            if (CollUtil.isEmpty(allObjDTOList) && CollUtil.isNotEmpty(firstReturnResult)) {
                firstReturnResult.forEach((item) -> item.setChangeStrategy("Change"));
            } else {
                Map<BigInteger, ECObjData> allECObjDataMap = (Map) allObjDTOList.stream().collect(
                        Collectors.toMap(ECObjDataVO::getOid, Function.identity(), (a, b) -> a));
                Map<BigInteger, ECObjDataVO> firstCollect = (Map) firstReturnResult.stream().collect(
                        Collectors.toMap(ECObjDataVO::getOid, Function.identity(), (a, b) -> a));

                for (Map.Entry<BigInteger, List<CTyIterateBaseDO>> entry : relationObjectMap.entrySet()) {
                    BigInteger entryKey = (BigInteger) entry.getKey();
                    ECObjData strategy = (ECObjData) allECObjDataMap.get(entryKey);

                    for (CTyIterateBaseDO iterateBaseDO : (List<CTyIterateBaseDO>) entry.getValue()) {
                        ECObjDataVO vo = (ECObjDataVO) firstCollect.get(iterateBaseDO.getOid());
                        if (!Objects.isNull(vo)) {
                            vo.setChangeStrategy(Objects.nonNull(strategy) ? strategy.getChangeStrategy() : "Change");
                        }
                    }
                }

            }
        }
    }

    private Map<BigInteger, List<CTyIterateBaseDO>> getECObjDataRelationObjectByList(List<ECObjData> allObjDTOList) {
        Map<String, List<ECObjData>> groupByOtype = (Map) allObjDTOList.stream().collect(
                Collectors.groupingBy((item) -> CharSequenceUtil.isBlank(item.getOtype()) ? "" : item.getOtype()));
        Map<BigInteger, List<CTyIterateBaseDO>> result = new HashMap();

        for (Map.Entry<String, List<ECObjData>> entry : groupByOtype.entrySet()) {
            String otypeKey = (String) entry.getKey();
            if (CharSequenceUtil.isBlank(otypeKey)) {
                TyException.throwSingleTyExceptionVarargs(ResponseCodeEnum.ACC_PARAMETER_IS_NULL,
                                                          new String[]{"otype"});
            }

            String temps = otypeKey.split("\\|")[0];
            Class<? extends CTyEntityBaseDO> aClass = TyEntityMapperUtil.getClassByOtype(temps);
            if (ITyCompanyVersioned.class.isAssignableFrom(aClass)) {
                List<ECObjData> value = (List) entry.getValue();
                result.putAll(this.getECObjDataRelationObject(otypeKey, value));
            }
        }

        TyplmLoggerUtil.debug(log, () -> "获取变更对象的关联对象为==>【{}】",
                              () -> new Object[]{JSON.toJSONString(result)});
        return result;
    }

    private List<ECObjDataVO> addObjectBeforeChangeWithStrategy(IdentifierEntity entity, List<ECObjDTO> ecObjDTOS,
                                                                Boolean before) {
        TyplmLoggerUtil.debug(log, () -> "变更对象标识为==>【{}】，变更前对象集合为==>【{}】",
                              () -> new Object[]{JSON.toJSONString(entity), JSON.toJSONString(ecObjDTOS)});
        this.tyChangeCheckService.changeObjectAddCheck(ecObjDTOS);
        Boolean chgFormProcessingFlag = this.typlmFlowContainerObjectService.checkObjInActiveFlowContainer(
                entity.getOid(), entity.getOtype());
        WorkFlowContainer workFlowContainer = null;
        if (Boolean.TRUE.equals(chgFormProcessingFlag)) {
            Map<String, Object> params = new HashMap();
            params.put("baseObjectOid", entity.getOid());
            params.put("baseObjectOtype", entity.getOtype());
            List<WorkFlowContainer> workFlowContainers = this.typlmWorkFlowContainerService.simpleQueryListByParams(
                    params);
            TyplmLoggerUtil.debug(log, () -> "根据变更对象获取的流程容器为==>【{}】",
                                  () -> new Object[]{JSON.toJSONString(workFlowContainers)});
            if (CollUtil.isNotEmpty(workFlowContainers)) {
                workFlowContainer = (WorkFlowContainer) workFlowContainers.get(0);
            }
        }

        for (ECObjDTO ecObjDTO : ecObjDTOS) {
            if (Boolean.TRUE.equals(chgFormProcessingFlag) && workFlowContainer != null) {
                this.typlmFlowContainerObjectService.insertRuFlowObject(workFlowContainer, ecObjDTO.getOid(),
                                                                        ecObjDTO.getOtype());
            }
        }

        if (!"ty.inteplm.change.CTyChangeNotice".equals(entity.getOtype())) {
            TyException.throwSingleTyExceptionVarargs(ResponseCodeEnum.ACC_PARAMETER_ENUM_ERROR,
                                                      new String[]{entity.getOtype()});
        }

        List<ChgActivityDO> ecaList = this.typlmChgNoticeActivityLinkMapper.queryECAByECNId(entity.getOid());
        ecaList = this.setEcaListWhenIsNull(ecaList, entity);
        if (Boolean.TRUE.equals(before)) {
            List<ECObjData> allBeforeObjVoList = new ArrayList();

            for (ChgActivityDO activityDO : ecaList) {
                List<ECObjDataVO> ecObjDataVOS = this.typlmChangeObjectLinkService.queryECObjList(
                        activityDO.getIdentifierRef(), Boolean.TRUE);
                allBeforeObjVoList.addAll(Convert.toList(ECObjData.class, ecObjDataVOS));
            }

            Map<BigInteger, List<CTyIterateBaseDO>> dataRelationObjectMap = this.getECObjDataRelationObjectByList(
                    allBeforeObjVoList);
            List<ECObjDataVO> firstResult = Convert.toList(ECObjDataVO.class, ecObjDTOS);
            this.resetAddObjectChangeStrategy(allBeforeObjVoList, firstResult, dataRelationObjectMap);
            Map<BigInteger, ECObjDTO> collect = (Map) ecObjDTOS.stream().collect(
                    Collectors.toMap(CTyEntityBaseDO::getOid, Function.identity(), (a, b) -> a));

            for (ECObjDataVO vo : firstResult) {
                ECObjDTO dto = (ECObjDTO) collect.get(vo.getOid());
                dto.setChangeStrategy(vo.getChangeStrategy());
            }
        }

        this.createEcObjAndEcaLink(ecaList, ecObjDTOS, before);
        List<ECObjDataVO> result = this.toTransformEcobj(ecaList, before);
        TyHandleEcCommonUtil.sortListByObjectName(result);
        return result;
    }

    private List<ECObjDataVO> toTransformEcobj(List<ChgActivityDO> ecaList, Boolean before) {
        List<ECObjDataVO> allECObjList = new ArrayList();

        for (ChgActivityDO chgActivityDO : ecaList) {
            IdentifierEntity eca = new IdentifierEntity(chgActivityDO.getOid(), chgActivityDO.getOtype());
            List<ECObjDataVO> ecObjDataVOS = this.typlmChangeObjectLinkService.queryECObjList(eca, before);
            allECObjList.addAll(ecObjDataVOS);
        }

        return (List<ECObjDataVO>) (CollectionUtils.isNotEmpty(allECObjList) ? (List) allECObjList.stream().distinct()
                .collect(Collectors.toList()) : new ArrayList());
    }

    private Map<BigInteger, List<CTyIterateBaseDO>> getECObjDataRelationObject(String otype,
                                                                               List<ECObjData> ecObjDataList) {
        Map<BigInteger, List<CTyIterateBaseDO>> result = new HashMap();
        TyplmLoggerUtil.debug(log, () -> "获取变更前对象的关联对象的入参==>otype =【{}】", () -> new Object[]{otype});
        if (!CollUtil.isEmpty(ecObjDataList) && !CharSequenceUtil.isBlank(otype)) {
            List<BigInteger> collect = (List) ecObjDataList.stream().map(ECObjDataVO::getOid).collect(
                    Collectors.toList());
            TyplmLoggerUtil.debug(log, () -> "关联对象的oid集合为==>【{}】",
                                  () -> new Object[]{JSON.toJSONString(collect)});
            if (otype.contains("ty.inteplm.part.CTyPart")) {
                Map<BigInteger, List<CTyIterateBaseDO>> bigIntegerListMap = this.getPartRelObjectByList(collect);
                result.putAll(bigIntegerListMap);
            } else if (otype.contains("ty.inteplm.cad.CTyCADDoc")) {
                Map<BigInteger, List<CTyIterateBaseDO>> bigIntegerListMap = this.getCadRefPartByListEx(collect);
                result.putAll(bigIntegerListMap);
                List<BigInteger> tempPartList = new ArrayList();

                for (Map.Entry<BigInteger, List<CTyIterateBaseDO>> entry : bigIntegerListMap.entrySet()) {
                    Set<BigInteger> setPartOid = (Set) ((List<CTyIterateBaseDO>) entry.getValue()).stream().map(
                                    CTyEntityBaseDO::getOid)
                            .collect(Collectors.toSet());
                    tempPartList.addAll(setPartOid);
                }

                if (CollUtil.isNotEmpty(tempPartList)) {
                    Map<BigInteger, List<CTyIterateBaseDO>> partListMap = this.getPartRelObjectByList(tempPartList);
                    result.putAll(partListMap);
                }
            }

            TyplmLoggerUtil.debug(log, () -> "获取的变更前的关联对象为==>【{}】",
                                  () -> new Object[]{JSON.toJSONString(result)});
            return result;
        } else {
            return result;
        }
    }

    private Map<BigInteger, List<CTyIterateBaseDO>> getCadRefPartByListEx(List<BigInteger> collect) {
        Map<BigInteger, List<CTyIterateBaseDO>> result = new HashMap();
        if (CollUtil.isEmpty(collect)) {
            return result;
        } else {
            List<CadLinkPartVO> tempList = new ArrayList();
            List<CadLinkPartVO> cadDescribeLinkPartVOS = this.typlmCADDescLinkService.queryCadLinkPart(collect, "");
            tempList.addAll(cadDescribeLinkPartVOS);
            List<CadLinkPartVO> cadBuildLinkPartVOS = this.typlmCADDescLinkService.queryCadLinkPart(collect, "all");
            tempList.addAll(cadBuildLinkPartVOS);
            Map<String, List<CadLinkPartVO>> describeAndBuildMap = (Map) tempList.stream().collect(
                    Collectors.groupingBy(CadLinkPartVO::getId));

            for (Map.Entry<String, List<CadLinkPartVO>> entry : describeAndBuildMap.entrySet()) {
                String key = (String) entry.getKey();
                List<CTyIterateBaseDO> doList = (List) result.get(key);
                if (CollUtil.isEmpty(doList)) {
                    doList = new ArrayList();
                    result.put(new BigInteger(key), doList);
                }

                for (CadLinkPartVO partVO : (List<CadLinkPartVO>) entry.getValue()) {
                    CTyIterateBaseDO iterateBaseDO = new CTyIterateBaseDO();
                    CadLinkPartBasicInfoVO basicInfoVO = partVO.getCadLinkPartBasicInfoVO();
                    iterateBaseDO.setOid(basicInfoVO.getPartId());
                    iterateBaseDO.setBranchid(basicInfoVO.getBranchid());
                    doList.add(iterateBaseDO);
                }
            }

            Map<BigInteger, List<BigInteger>> calculatePartList = this.typlmCADRelObjectService.batchQueryCalculatePartByDrw(
                    collect);

            for (Map.Entry<BigInteger, List<BigInteger>> entry : calculatePartList.entrySet()) {
                BigInteger key = (BigInteger) entry.getKey();
                List<CTyEntityBaseDO> cTyEntityBaseDOList = CommonUtil.batchQueryEntityList((List) entry.getValue(),
                                                                                            "ty.inteplm.part.CTyPart");
                List<CTyIterateBaseDO> doList = (List) result.get(key);
                if (CollUtil.isEmpty(doList)) {
                    doList = new ArrayList();
                    result.put(key, doList);
                }

                for (CTyEntityBaseDO aDo : cTyEntityBaseDOList) {
                    CTyIterateBaseDO iterateBaseDO = new CTyIterateBaseDO();
                    PartDO partDO = (PartDO) aDo;
                    iterateBaseDO.setOid(partDO.getOid());
                    iterateBaseDO.setBranchid(partDO.getBranchid());
                    iterateBaseDO.setOtype(partDO.getOtype());
                    iterateBaseDO.setMasteredoid(partDO.getMasteredoid());
                    iterateBaseDO.setMasteredotype(partDO.getMasteredotype());
                    doList.add(iterateBaseDO);
                }
            }

            TyplmLoggerUtil.debug(log, () -> "批量获取cad的关联对象为==>【{}】",
                                  () -> new Object[]{JSON.toJSONString(result)});
            return result;
        }
    }

    private Map<BigInteger, List<CTyIterateBaseDO>> getPartRelObjectByList(List<BigInteger> partList) {
        Map<BigInteger, List<CTyIterateBaseDO>> result = new HashMap();
        if (CollUtil.isEmpty(partList)) {
            return result;
        } else {
            Map<BigInteger, List<CADDocDO>> bigIntegerListMap = this.typlmPartRelObjectService.batchQueryLinkCadMapByPartList(
                    partList);
            if (CollUtil.isEmpty(bigIntegerListMap)) {
                return result;
            } else {
                for (Map.Entry<BigInteger, List<CADDocDO>> entry : bigIntegerListMap.entrySet()) {
                    BigInteger key = (BigInteger) entry.getKey();
                    List<CADDocDO> value = (List) entry.getValue();
                    List<CTyIterateBaseDO> temp = new ArrayList();

                    for (CADDocDO aDo : value) {
                        CTyIterateBaseDO iterateBaseDO = new CTyIterateBaseDO();
                        iterateBaseDO.setOid(aDo.getOid());
                        iterateBaseDO.setOtype(aDo.getOtype());
                        iterateBaseDO.setMasteredoid(aDo.getMasteredoid());
                        iterateBaseDO.setMasteredotype(aDo.getMasteredotype());
                        iterateBaseDO.setBranchid(aDo.getBranchid());
                        iterateBaseDO.setBranchidtypedefref(aDo.getBranchidtypedefref());
                        temp.add(iterateBaseDO);
                    }

                    result.put(key, temp);
                }

                TyplmLoggerUtil.debug(log, () -> "批量获取零件的关联文档并转化对象的出参为==>【{}】",
                                      () -> new Object[]{JSON.toJSONString(result)});
                return result;
            }
        }
    }

    private void resetDefaultWorkOwner(IdentifierEntity entity, List<ECObjDataVO> resultList) {
        UserDO tempUser = CommonUtil.getUser();
        if (!Objects.isNull(entity) && !TyplmEntityBaseUtil.isEmptyOid(entity.getOid()) && !StringUtils.isBlank(
                entity.getOtype())) {
            TyplmLoggerUtil.debug(log,
                                  () -> "有主对象,通告主对象获取对象的创建者，判断创建者是否存在，存在设置创建者为工作负责人，不存在设置当前用户为工作负责人");
            String otype = entity.getOtype();
            if ("ty.inteplm.change.CTyChangeNotice".equals(otype)) {
                CTyEntityBaseDO entityBaseDO = CommonUtil.getEntity(entity);
                if (entityBaseDO instanceof ITyCreator) {
                    BigInteger creatoroid = ((ITyCreator) entityBaseDO).getCreatoroid();
                    if (!TyplmEntityBaseUtil.isEmptyOid(creatoroid)) {
                        UserDO userDO = this.typlmUserService.queryUserByKey(creatoroid);
                        if (Objects.nonNull(userDO)) {
                            tempUser = userDO;
                        }
                    }
                }

                this.resetWorker(entity, tempUser, resultList);
            }
        } else {
            TyplmLoggerUtil.debug(log, () -> "没有主对象,设置当前用户为工作负责人");
            this.resetWorker(entity, tempUser, resultList);
        }
    }

    public List<ECObjDataVO> batchTransformEntityToECObject(IdentifierEntity entity, List<ECObjDTO> ecObjDTOList,
                                                            Boolean before) {
        TyplmLoggerUtil.debug(log, () -> "批量转换实体对象为变更对象，需要添加的对象列表为",
                              () -> new Object[]{JSON.toJSONString(ecObjDTOList)});
        if (CollUtil.isEmpty(ecObjDTOList)) {
            TyException.throwSingleTyExceptionVarargs(ResponseCodeEnum.ACC_PARAMETER_IS_NULL,
                                                      new String[]{"entityList"});
        }

        if (ecObjDTOList.stream().anyMatch((item) -> TyplmEntityBaseUtil.isEmptyOid(item.getOid()))) {
            TyException.throwSingleTyExceptionVarargs(ResponseCodeEnum.ACC_PARAMETER_IS_NULL, new String[]{"oid"});
        }

        if (ecObjDTOList.stream().anyMatch((item) -> StringUtils.isBlank(item.getOtype()))) {
            TyException.throwSingleTyExceptionVarargs(ResponseCodeEnum.ACC_PARAMETER_IS_NULL, new String[]{"otype"});
        }

        List<IdentifierEntity> entityList = (List) ecObjDTOList.stream().map(CTyEntityBaseDO::getIdentifierRef).collect(
                Collectors.toList());
        List<TyEntityBasicInfo> basicInfoList = TyCommonSearchUtil.batchQueryEntityDetail(entityList);
        List<ECObjDataVO> resultList = new ArrayList();
        if (ObjectUtils.isEmpty(basicInfoList)) {
            return resultList;
        } else {
            for (TyEntityBasicInfo entityBasicInfo : basicInfoList) {
                resultList.add(this.convertToObjData(entityBasicInfo));
            }

            if (Boolean.TRUE.equals(before)) {
                TyplmLoggerUtil.debug(log, () -> "当前对象是变更前对象，需设置默认工作负责人和默认策略");
                this.resetDefaultWorkOwner(entity, resultList);
                this.resetDefaultChangeStrategy(resultList);
            }

            return resultList;
        }
    }

    private void resetDefaultChangeStrategy(List<ECObjDataVO> resultList) {
        TyplmLoggerUtil.debug(log, () -> "设置默认变更策略");
        if (!CollUtil.isEmpty(resultList)) {
            resultList.forEach((item) -> item.setChangeStrategy("Change"));
        }
    }

    private ECObjDataVO convertToObjData(TyEntityBasicInfo entityBasicInfo) {
        TyplmLoggerUtil.debug(log, () -> "当前通用对象信息为==>【{}】",
                              () -> new Object[]{JSON.toJSONString(entityBasicInfo)});
        ECObjDataVO ecObjDataVO = new ECObjDataVO();
        BeanUtils.copyProperties(entityBasicInfo, ecObjDataVO);
        ecObjDataVO.setNumber(entityBasicInfo.getObjectNumber());
        ecObjDataVO.setTypeDefName(entityBasicInfo.getTypeDisplayName());
        ecObjDataVO.setLifecycleStageKey(entityBasicInfo.getLifecyclestagekey());
        ecObjDataVO.setLifecycleName(entityBasicInfo.getLifecyclestagekeyName());
        ecObjDataVO.setViewName(entityBasicInfo.getViewDefName());
        ecObjDataVO.setContainerOid(entityBasicInfo.getContaineroid());
        ecObjDataVO.setContainerOtype(entityBasicInfo.getContainerotype());
        ecObjDataVO.setIteration(entityBasicInfo.getIterationid());
        ecObjDataVO.setViewDefOid(entityBasicInfo.getViewdefoid());
        ecObjDataVO.setTypeOid(entityBasicInfo.getTypeoid());
        ecObjDataVO.setTypeotype(entityBasicInfo.getTypeotype());
        ecObjDataVO.setVariation1(entityBasicInfo.getVariation1());
        ecObjDataVO.setVariation2(entityBasicInfo.getVariation2());
        ecObjDataVO.setCompanyversion(entityBasicInfo.getCompanyversion());
        ecObjDataVO.setSecuritylabels(entityBasicInfo.getSecuritylabels());
        ecObjDataVO.setLockstateinfo(entityBasicInfo.getLockstateinfo());
        if (StringUtils.isNotEmpty(ecObjDataVO.getVariation1())) {
            Map<String, String> map = this.typlmLocalePropertyValueService.queryLocaleValueByItem(
                    Collections.singletonList(ecObjDataVO.getVariation1()), "PurposeOfBOM",
                    TyCommonExtUtil.getFrontLanguage());
            ecObjDataVO.setDisplayVariation1((String) map.get(ecObjDataVO.getVariation1()));
        }

        if (StringUtils.isNotEmpty(ecObjDataVO.getVariation2())) {
            Map<String, String> map = this.typlmLocalePropertyValueService.queryLocaleValueByItem(
                    Collections.singletonList(ecObjDataVO.getVariation2()), "SpareBOM",
                    TyCommonExtUtil.getFrontLanguage());
            ecObjDataVO.setDisplayVariation2((String) map.get(ecObjDataVO.getVariation2()));
        }

        TyplmLoggerUtil.debug(log, () -> "转化后的对象信息为==>【{}】",
                              () -> new Object[]{JSON.toJSONString(ecObjDataVO)});
        return ecObjDataVO;
    }

    private void resetWorker(IdentifierEntity entity, UserDO user, List<ECObjDataVO> resultList) {
        TyplmLoggerUtil.debug(log, () -> "设置工作负责人");
        //        IdentifierEntity entity = detailDTO.getEntity();
        if (Objects.isNull(entity)) {
            this.resetWorker(entity, CommonUtil.getUser(), resultList);
        } else if (!TyplmEntityBaseUtil.isEmptyOid(entity.getOid()) && !StringUtils.isBlank(entity.getOtype())) {
            String otype = entity.getOtype();
            if ("ty.inteplm.change.CTyChangeNotice".equals(otype)) {
                CTyEntityBaseDO entityBaseDO = CommonUtil.getEntity(entity);
                if (!(entityBaseDO instanceof ITyCreator)) {
                    this.resetWorker(entity, CommonUtil.getUser(), resultList);
                } else {
                    BigInteger creatoroid = ((ITyCreator) entityBaseDO).getCreatoroid();
                    if (TyplmEntityBaseUtil.isEmptyOid(creatoroid)) {
                        this.resetWorker(entity, CommonUtil.getUser(), resultList);
                    } else {
                        UserDO userDO = this.typlmUserService.queryUserByKey(creatoroid);
                        if (Objects.isNull(userDO)) {
                            this.resetWorker(entity, CommonUtil.getUser(), resultList);
                        } else {
                            this.resetWorker(entity, userDO, resultList);
                        }
                    }
                }
            }
        } else {
            this.resetWorker(entity, CommonUtil.getUser(), resultList);
        }
    }
}